package handel

import (
	"context"
	"encoding/json"
	"goods_srv/global"
	pb "goods_srv/goods"
	"goods_srv/types"
	"gorm.io/gorm"
	"strconv"
	"time"
)

type GoodsSrvHandel struct {
	pb.UnimplementedGoodsServer
}

func NewGoodsSrvHandel() *GoodsSrvHandel {
	return &GoodsSrvHandel{}
}

func (l *GoodsSrvHandel) GoodsAdd(ctx context.Context, req *pb.GoodsAddReq) (*pb.GoodsAddResp, error) {
	//信息验证、数据库存储、库存管理

	if req.GoodsPrice == req.SubPrice {
		return &pb.GoodsAddResp{
			Code: -1,
			Msg:  "商品无折扣",
		}, nil
	}

	if req.Discount >= 1 {
		return &pb.GoodsAddResp{
			Code: -2,
			Msg:  "商品折扣格式错误",
		}, nil
	}

	if req.GoodsStock < req.GoodsNum {
		return &pb.GoodsAddResp{
			Code: -3,
			Msg:  "商品超卖",
		}, nil
	}

	goods := types.Goods{
		GoodsTitle:  req.GoodsTitle,
		ImageUrl:    req.ImageUrl,
		Introduce:   req.Introduce,
		GoodsPrice:  int(req.GoodsPrice),
		SubPrice:    int(req.SubPrice),
		Discount:    float64(req.Discount),
		GoodsStock:  int(req.GoodsStock),
		GoodsNum:    int(req.GoodsNum),
		GoodsStatus: int(req.GoodsStatus),
	}

	global.Db.Table("goods").Create(&goods)

	gId := strconv.Itoa(int(goods.ID))

	//库存管理  库存的数量
	global.RedisClient.Set("GoodsStock"+gId, req.GoodsStock, time.Hour*24)
	//卖出的商品数量
	global.RedisClient.Set("GoodsNum"+gId, req.GoodsNum, time.Hour*24)

	return &pb.GoodsAddResp{
		Code: 0,
		Msg:  "商品发布",
	}, nil
}

func (l *GoodsSrvHandel) GoodsList(ctx context.Context, req *pb.GoodsListReq) (*pb.GoodsListResp, error) {
	//商品列表查询接口，支持分页查询及筛选条件如商品名称、价格范围、库存状态等。

	db := global.Db.Table("goods")

	switch req.GoodsType {
	case 1:
		db.Where("goods_title = ?", req.GoodsText)
		break
	case 2:
		db.Where("goods_price > ?", req.GoodsText)
		break
	case 3:
		db.Where("goods_status = ?", req.GoodsText)
		break
	default:
		break
	}

	offsetPage := (req.Page - 1) * req.PageSize

	var goodsList []types.Goods

	db.Limit(int(req.PageSize)).Offset(int(offsetPage))

	db.Find(&goodsList)

	var goodsTeam []*pb.GoodsTeam

	for _, v := range goodsList {
		goodsTeam = append(goodsTeam, &pb.GoodsTeam{
			Id:          int64(v.ID),
			GoodsTitle:  v.GoodsTitle,
			ImageUrl:    v.ImageUrl,
			Introduce:   v.Introduce,
			GoodsPrice:  int64(v.GoodsPrice),
			SubPrice:    int64(v.SubPrice),
			Discount:    float32(v.Discount),
			GoodsStock:  int64(v.GoodsStock),
			GoodsNum:    int64(v.GoodsNum),
			GoodsStatus: int64(v.GoodsStatus),
		})
	}

	marshal, err := json.Marshal(goodsTeam)
	if err != nil {
		return nil, err
	}

	global.RedisClient.Set("GoodsInfo"+req.GoodsText, marshal, time.Hour*24)

	return &pb.GoodsListResp{List: goodsTeam}, nil
}

func (l *GoodsSrvHandel) GoodsInfo(ctx context.Context, req *pb.GoodsInfoReq) (*pb.GoodsInfoResp, error) {
	//展示商品详细信息，支持缓存优化及防止缓存击穿的策略。

	gID := strconv.Itoa(int(req.Id))

	result, err := global.RedisClient.Get("GoodsStock" + gID).Result()
	if err != nil {
		return nil, err
	}

	stock, err := strconv.Atoi(result)
	if err != nil {
		return nil, err
	}

	list := types.Goods{
		Model:      gorm.Model{ID: uint(req.Id)},
		GoodsStock: stock,
	}

	global.Db.Table("goods").Where("id = ? and goods_stock = ?", req.Id, stock).First(&list)

	marshal, err := json.Marshal(list)
	if err != nil {
		return nil, err
	}

	global.RedisClient.SetNX("GoodsInfo", marshal, time.Hour*24)
	global.RedisClient.Set("GoodsInfo", marshal, time.Hour*24)

	return &pb.GoodsInfoResp{
		Id:          int64(list.ID),
		GoodsTitle:  list.GoodsTitle,
		ImageUrl:    list.ImageUrl,
		Introduce:   list.Introduce,
		GoodsPrice:  int64(list.GoodsPrice),
		SubPrice:    int64(list.SubPrice),
		Discount:    float32(list.Discount),
		GoodsStock:  int64(list.GoodsStock),
		GoodsNum:    int64(list.GoodsNum),
		GoodsStatus: int64(list.GoodsStatus),
	}, nil
}

func (l *GoodsSrvHandel) GoodsRecommend(ctx context.Context, req *pb.GoodsRecommendReq) (*pb.GoodsRecommendResp, error) {
	//基于用户历史行为或商品标签推荐相关商品

	var goodsList []types.Goods

	global.Db.Table("goods").Where("goods_status = ?", req.GoodsStatus).Find(&goodsList)

	var goodsTeam []*pb.GoodsTeam

	for _, v := range goodsList {
		goodsTeam = append(goodsTeam, &pb.GoodsTeam{
			Id:          int64(v.ID),
			GoodsTitle:  v.GoodsTitle,
			ImageUrl:    v.ImageUrl,
			Introduce:   v.Introduce,
			GoodsPrice:  int64(v.GoodsPrice),
			SubPrice:    int64(v.SubPrice),
			Discount:    float32(v.Discount),
			GoodsStock:  int64(v.GoodsStock),
			GoodsNum:    int64(v.GoodsNum),
			GoodsStatus: int64(v.GoodsStatus),
		})
	}

	marshal, err := json.Marshal(goodsTeam)
	if err != nil {
		return nil, err
	}

	global.RedisClient.Set("GoodsRecommend", marshal, time.Hour*24)

	return &pb.GoodsRecommendResp{List: goodsTeam}, nil
}
